package Utils.io.json;

import Utils.io.IOUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.*;

/**
 * @author d11yu
 */
public class GsonUtils {
    private static GsonUtils instance;
    private static Gson gson;

    public Gson getMapper() {
        return gson;
    }

    public void setMapper(Gson gson) {
        GsonUtils.gson = gson;
    }


    private GsonUtils() {
        gson = new Gson();
    }

    public static GsonUtils getInstance() {
        if (instance == null) {
            instance = new GsonUtils();
        }
        return instance;
    }

    /**
     * Jackson Json反序列化为List。
     *
     * @param jsonStr
     * @param typeToken 例：new TypeToken<Map<Integer, Person>>() {}
     * @param <T>
     * @return
     */
    public <T> T deserializeListOrMap(String jsonStr, TypeToken<T> typeToken) {
        return gson.fromJson(jsonStr, typeToken.getType());
    }

    /**
     * Jackson Json反序列化为List。
     *
     * @param is
     * @param typeToken 例：new TypeToken<Map<Integer, Person>>() {}
     * @param <T>
     * @return
     */
    public <T> T deserializeListOrMap(InputStream is, TypeToken<T> typeToken) {
        return gson.fromJson(new InputStreamReader(is), typeToken.getType());
    }

    /**
     * Jackson Json反序列化为List。
     *
     * @param path
     * @param typeToken 例：new TypeToken<Map<Integer, Person>>() {}
     * @param <T>
     * @return
     * @throws FileNotFoundException
     */
    public <T> T deserializeListOrMapFromFile(String path, TypeToken<T> typeToken) throws FileNotFoundException {
        return gson.fromJson(new InputStreamReader(new FileInputStream(path)), typeToken.getType());
    }

    /**
     * Jackson Json反序列化为Java Bean
     *
     * @param jsonStr   json字符串
     * @param classType 目标对象类型
     * @param <T>
     * @return 返回目标对象
     */
    public <T> T deserialize(String jsonStr, Class<T> classType) {
        return gson.fromJson(jsonStr, classType);
    }

    /**
     * Jackson Json反序列化为Java Bean
     *
     * @param is        InputStream
     * @param classType 目标对象类型
     * @param <T>       目标对象类型
     * @return 返回目标对象
     */
    public <T> T deserialize(InputStream is, Class<T> classType) {
        InputStreamReader reader = new InputStreamReader(is);
        return gson.fromJson(reader, classType);
    }

    /**
     * Jackson Json反序列化为Java Bean
     *
     * @param path      json文件路径
     * @param classType 目标对象类型
     * @param <T>       目标对象类型
     * @return 返回目标对象
     * @throws IOException 异常
     */
    public <T> T deserializeFile(String path, Class<T> classType) throws IOException {
        return deserialize(IOUtils.file2InputStream(path), classType);
    }

    /**
     * 序列化对象
     *
     * @param obj
     * @return
     */
    public String serialize(Object obj) {
        return gson.toJson(obj);
    }
}
